<?php
abstract class Config_Abstract implements ArrayAccess , Iterator{
    /**
     * Config Data
     * @var array
     */
     protected $_data = array();
     
     /**
      * Config name
      * @var string
      */
     protected $_name;
     
     public function __construct($name){
         $this->_name = $name;
     }
     
 	/**
      * Return data array
      * @return array
      */
     public function __toArray(){
         return $this->_data;
     }
     /**
      * Get Items count
      * @return integer
      */
     public function getCount(){
     	return count($this->_data);
     }    
     /**
      * Get property from config
      * @param string $key
      * @throws Exception
      * @return mixed
      */
     public function get($key){
         if(array_key_exists((string)$key, $this->_data))
             return $this->_data[$key];
         else 
             throw new Exception('Config::get Invalid key '.$key); 
     }
     /**
      * Set value
      * @param string $key
      * @param mixed $value
      */
     public function set($key , $value){
         $this->_data[$key] = $value;
     }
     /**
      * Set data from array
      * @param array $data
      */
     public function setData(array $data){
     	if(empty($data))
     		return;
     	
     	foreach ($data as $k=>$v)
     		$this->_data[$k]=$v;
     }
 	/**
     * Remove item by key
     * @param string $key
     * @boolean
     */
    public function remove($key){
    	if(isset($this->_data[$key]))
    		unset($this->_data[$key]);
    	return true;	
    }
    /**
     * Start of ArrayAccess implementation
     */
	public function offsetSet($offset, $value) {
   		if (is_null($offset)) {
            $this->_data[] = $value;
        } else {
            $this->_data[$offset] = $value;
        }
    }
    public function offsetExists($offset) {
        return isset($this->_data[$offset]);
    }
    public function offsetUnset($offset) {
        unset($this->_data[$offset]);
    }
    public function offsetGet($offset) {
        return isset($this->_data[$offset]) ? $this->_data[$offset] : null;
    }
    /**
     * End of ArrayAccess implementation
     */
    
    /**
     * Start of Iterator implementation
     */
    public function rewind() {
       reset($this->_data);
    }

    public function current() {
        return $this->_data[key($this->_data)];
    }

    public function key() {
        return key($this->_data);
    }

    public function next() {
       next($this->_data);
    }

    public function valid() {
        return isset($this->_data[key($this->_data)]);
    }
    /**
     * End of Iterator implementation
     */
    
    /**
     * Get data handle
     * Hack method. Do not use it without understanding.
     * @return array
     */
    public function & dataLink(){
    	return $this->_data;
    }
}